package com.huaxindata.im.model.utils;

import com.huaxin.common.tools.Log;
import com.huaxindata.im.model.entity.ChatFileMessageBody;
import com.huaxindata.im.model.entity.ChatImageMessageBody;
import com.huaxindata.im.model.entity.ChatLocationMessageBody;
import com.huaxindata.im.model.entity.ChatMessage;
import com.huaxindata.im.model.entity.ChatMessageBody;
import com.huaxindata.im.model.entity.ChatNewsMessageBody;
import com.huaxindata.im.model.entity.ChatStationMessageBody;
import com.huaxindata.im.model.entity.ChatSvgMessageBody;
import com.huaxindata.im.model.entity.ChatSysMessageBody;
import com.huaxindata.im.model.entity.ChatTargetMessageBody;
import com.huaxindata.im.model.entity.ChatTextMessageBody;
import com.huaxindata.im.model.entity.ChatVideoMessageBody;
import com.huaxindata.im.model.entity.ChatVoiceMessageBody;
import com.huaxindata.im.model.entity.ChatWarnMessageBody;
import com.huaxindata.im.model.entity.ChatWorktaskMessageBody;

import org.eclipse.paho.client.mqttv3.MqttMessage;

import java.nio.ByteBuffer;

/**
 * @author lwjing
 * @date 2018/1/9
 * @Desc 接收消息后，消息解析
 * Copyright HUAXIN DATA. All rights reserved.
 */
public class ReceivePlayload {


    //magic数，扩展2为0占8个字节
    private static final byte[] MAGIC           = {0x68, 0x75, 0x61, 0x78, 0x69, 0x6E, 0x00, 0x00};//huaxin
    // MAGIC（8个字节） + 消息类型（2个字节） +  发送人的字节长度（1个字节） + 接收人的字节长度（1个字节）+ 消息文本的长度(1 - 1000)(4个字节) + 发送时间(8个字节) + 消息文本
    private static final int    PLAYLOAD_LENGTH = 24;

    /**
     * 接收到的mqttmessage，根据其type类型做解析
     * @param mqttMessage
     * @return
     */
    public static ChatMessage parseMqttMessage(MqttMessage mqttMessage) {
        byte[] data = mqttMessage.getPayload();
        final int dataLen = data.length;
        final ByteBuffer buffer = ByteBuffer.wrap(data);

        if (isInvalidMessage(buffer)) {
            return null;
        }

        ChatMessage chatMessage = new ChatMessage();
        //类型 2
        final byte[] type = get(buffer, 2);

        chatMessage.type=type[1];
        //发送人 1
        byte fromlen = buffer.get();
        //接收人 1
        byte tolen = buffer.get();
        //消息内容 4
        int mlen = bytesToInt(get(buffer, 4), 0);

        if (PLAYLOAD_LENGTH + fromlen + tolen + mlen != dataLen) {
            Log.d("xxx","Invalid length!" + dataLen);
            return null;
        }
        //发送时间 8
        chatMessage.timestamp = bytes2long(get(buffer, 8));
        byte[] content = get(buffer, fromlen + tolen + mlen);
        chatMessage.sender = new String(content, 0, fromlen);
        chatMessage.receiver = new String(content, fromlen, tolen);
        chatMessage.message=new String(content, fromlen + tolen, mlen);
        chatMessage.messageBody=getMessageBodyByType(type[1],new String(content, fromlen + tolen, mlen));
        //消息接收处理成功
        chatMessage.messageState = ChatMessage.Status.SUCCESS;
        return chatMessage;
    }

    /**
     * 
     * @param type
     * @param content
     * @return  通过type 解析不同的chatMessageBody
     */
    public static ChatMessageBody getMessageBodyByType(int type, String content) {
        switch (type) {
            case ChatMessageBody.Type.TEXT://文本
                 ChatTextMessageBody chatTextMessageBodybody=new ChatTextMessageBody(type);
                 chatTextMessageBodybody.setContent(content);
                 return chatTextMessageBodybody;

            case ChatMessageBody.Type.IMAGE://图片
                ChatImageMessageBody chatImageMessageBody=new ChatImageMessageBody(type);
                chatImageMessageBody.parseFileMessage(content);
               return chatImageMessageBody;

            case ChatMessageBody.Type.LOCATION://位置
                ChatLocationMessageBody chatLocationMessageBody=new ChatLocationMessageBody(type);
                chatLocationMessageBody.parseLocationMessage(content);
                return chatLocationMessageBody;

            case ChatMessageBody.Type.VOICE://语音
                ChatVoiceMessageBody  chatVoiceMessageBody=new ChatVoiceMessageBody(type);
                chatVoiceMessageBody.parseFileMessage(content);
                chatVoiceMessageBody.duration = chatVoiceMessageBody.getMediaLength(chatVoiceMessageBody.getLocalPath());
              return chatVoiceMessageBody;

            case ChatMessageBody.Type.FILE://文件
                ChatFileMessageBody chatFileMessageBody=new ChatFileMessageBody(type);
                chatFileMessageBody.parseFileMessage(content);
                return chatFileMessageBody;

            case ChatMessageBody.Type.VIDEO://短视频
                ChatVideoMessageBody chatVideoMessageBody=new ChatVideoMessageBody(type);
                chatVideoMessageBody.parseFileMessage(content);
                return chatVideoMessageBody;

            case ChatMessageBody.Type.STATION://站点
                ChatStationMessageBody chatStationMessageBody=new ChatStationMessageBody(type);
                chatStationMessageBody.parseStationMessage(content);
                return chatStationMessageBody;
                
            case ChatMessageBody.Type.SVG://Svg
                Log.e("lwjing","text SVG :"+content);
                ChatSvgMessageBody chatSvgMessageBody=new ChatSvgMessageBody(type);
                chatSvgMessageBody.parseSvgMessage(content);
                return chatSvgMessageBody;

            case ChatMessageBody.Type.WARN://告警
                Log.e("lwjing","text WARN :"+content);
                ChatWarnMessageBody chatWarnMessageBody=new ChatWarnMessageBody(type);
                chatWarnMessageBody.parseWarnMessage(content);
                return chatWarnMessageBody;

            case ChatMessageBody.Type.WORKTASK://工单
                Log.e("lwjing","text WORKTASK :"+content);
                ChatWorktaskMessageBody chatWorkOrderMessageBody=new ChatWorktaskMessageBody(type);
                chatWorkOrderMessageBody.setContent(content);
                return chatWorkOrderMessageBody;

            case ChatMessageBody.Type.TARGET://指标
                Log.e("lwjing","text TARGET :"+content);
                ChatTargetMessageBody chatTargetMessageBody=new ChatTargetMessageBody(type);
                chatTargetMessageBody.setContent(content);
                return chatTargetMessageBody;

            case ChatMessageBody.Type.NEWS://新闻
                Log.e("lwjing","text NEWS :"+content);
                 ChatNewsMessageBody chatNewsMessageBody=new ChatNewsMessageBody(type);
                chatNewsMessageBody.setContent(content);
                return chatNewsMessageBody;
            case ChatMessageBody.Type.SYSTEM://系统消息
                ChatSysMessageBody chatSysMessageBody=new ChatSysMessageBody(type);
                chatSysMessageBody.setContent(content);
                return chatSysMessageBody;
            default:
                return new ChatMessageBody(type);
        }
    }

    private static long bytes2long(byte[] b) {
        long temp = 0;
        long res = 0;
        for (int i = 0; i < 8; i++) {
            res <<= 8;
            temp = b[i] & 0xff;
            res |= temp;
        }
        return res;
    }

    private static int bytesToInt(byte[] ary, int offset) {
        int value;
        value = (ary[offset] & 0xFF)
                | ((ary[offset + 1] << 8) & 0xFF00)
                | ((ary[offset + 2] << 16) & 0xFF0000)
                | ((ary[offset + 3] << 24) & 0xFF000000);
        return value;
    }

    /**
     * @param buffer
     * @param length 从buffer中读取的length长度的字节数组
     * @return
     */
    private static byte[] get(ByteBuffer buffer, int length) {
        byte[] read = new byte[length];
        buffer.get(read);
        return read;
    }

    /**
     * @param buffer
     * @return 判断mqttMessage消息是否为有效消息
     */
    private static boolean isInvalidMessage(ByteBuffer buffer) {

        final byte[] magic = get(buffer, MAGIC.length);
        for (int i = 0; i < MAGIC.length; i++) {
            if (magic[i] != MAGIC[i]) {
                Log.d("xxx", "Invalid message!" + String.valueOf(magic));
                return true;
            }
        }
        return false;
    }
}
